#ifndef _LOCKER_H_
#define _LOCKER_H_

#include <pthread.h>
#include <exception>
#include <semaphore.h>

/* 线程同步机制封装 */

/* 互斥锁 */
class Locker
{
public:
    Locker()
    {
        // 初始化锁！初始化失败抛出异常！
        if (pthread_mutex_init(&_mtx, nullptr) != 0)
        {
            throw std::exception();
        }
    }

    ~Locker()
    {
        pthread_mutex_destroy(&_mtx); // 销毁锁
    }

    /* 加锁 */
    bool lock()
    {
        return pthread_mutex_lock(&_mtx) == 0;
    }

    /* 解锁 */
    bool unlock()
    {
        return pthread_mutex_unlock(&_mtx) == 0;
    }

    /* 获取互斥锁 */
    pthread_mutex_t *GetMutex()
    {
        return &_mtx;
    }

private:
    pthread_mutex_t _mtx; // 声明锁
};

/* 条件变量 */
class Cond
{
public:
    Cond()
    {
        // 初始条件变量
        if (pthread_cond_init(&_cond, nullptr) != 0)
        {
            throw std::exception();
        }
    }

    ~Cond()
    {
        pthread_cond_destroy(&_cond);
    }

    // 等待
    bool Wait(pthread_mutex_t *mtx)
    {
        return pthread_cond_wait(&_cond, mtx) == 0;
    }

    //
    bool TimeWait(pthread_mutex_t *mtx, struct timespec t)
    {
        return pthread_cond_timedwait(&_cond, mtx, &t) == 0;
    }

    // 唤醒单个
    bool Signal()
    {
        return pthread_cond_signal(&_cond) == 0;
    }

    // 全部唤醒
    bool BroadCast()
    {
        return pthread_cond_broadcast(&_cond) == 0;
    }

private:
    pthread_cond_t _cond;
};

/* 信号量 */

class Sem
{
public:
    Sem()
    {
        if (sem_init(&_sem, 0, 0) != 0)
        {
            throw std::exception();
        }
    }

    Sem(int sem)
    {
        if (sem_init(&_sem, 0, sem) != 0)
        {
            throw std::exception();
        }
    }

    ~Sem()
    {
        sem_destroy(&_sem);
    }

    // 等待信号量
    bool Wait(){
        return  sem_wait(&_sem) == 0;
    }

    // 增加信号量
    bool Post(){
        return sem_post(&_sem) == 0;
    }

private:
    sem_t _sem;
};

#endif